#include "app_device.h"
#include <unistd.h>
#include "app_pool.h"
#include "fcntl.h"
static int send_task_fun(void *arg){
    Device *dev = (Device *)arg;
    char data[128];
    app_buffer_read(dev->read_buffer,data,3);
    app_buffer_read(dev->read_buffer,data+3,data[1]+data[2]);
    int len=data[1]+data[2]+3;
    if(dev->funs->send_msg){
        dev->funs->send_msg(dev,data,len);
    }
}

//不断读取设备数据发送到服务器的线程
static void *read_thread_fun(void *arg){
    Device *dev = (Device *)arg;
    char data[128];
    while(dev->running==1){
        memset(data,0,sizeof(data));
        int len=read(dev->fd,data,sizeof(data));
        //调用post_read做后置处理
        if(dev->funs->post_read){
            len=dev->funs->post_read(dev,data,len);
        }
        //将处理后的数据保存到读缓存中
        app_buffer_write(dev->read_buffer,data,len);
        //注册发送消息的任务
        app_pool_registerTask(send_task_fun,dev);
    }
}

//初始化设备
Device *app_device_init(char *filname){
    Device *dev = (Device *)malloc(sizeof(Device));
    dev->filname = filname;
    dev->fd = open(filname,O_CREAT|O_RDWR,0644);
    dev->read_buffer = app_buffer_init(1024);
    dev->write_buffer = app_buffer_init(1024);
    dev->conn_type=CONN_NONE;
    dev->dev_type=DEV_GENERAL;
    dev->running=0;
    dev->funs=malloc(sizeof(DeviceFuns));
    return dev;
}

//启动设备
int app_device_start(Device *dev){
    if(dev->running==1){
        log_debug("device is running");
        return 0;
    }
    dev->running = 1;
    //创建启动线程
    if(pthread_create(&dev->read_thread,NULL,read_thread_fun,dev)){
        log_error("pthread_create error");
        dev->running = 0;
        return -1;
    }
    return 0;
}
//停止设备
int app_device_stop(Device *dev)
{
    if(dev->running==0){
        log_debug("device is already stop");
        return 0;
    }
    pthread_cancel(dev->read_thread);
    pthread_join(dev->read_thread,NULL);
    dev->running = 0;
    return 0;
}
//关闭释放设备
void app_device_close(Device *dev){
    app_buffer_free(dev->read_buffer);
    app_buffer_free(dev->write_buffer);

    free(dev->funs);
    free(dev);
}